import React from "react";
import {forEach, isArray, isBoolean, isEmpty, isFunction, isNumber, isString, map} from "lodash-es";
import {isDateIns, isNotEmpty, myFormatTime, QueryFilter} from "jh-utils";
import {ComponentType} from "../../Config";
import {previewNumber} from "./compValuePreview";
import ComboBase from "../../ComboBox/ComboBase";

/**
 * 过滤条件的枚举数据
 * @type {{week1: {code: string, name: string}, month1: {code: string, name: string}, no: {code: string, name: string}, ltEq: {preview: string, code: string, name: string}, yes: {code: string, name: string}, lt: {preview: string, code: string, name: string}, gtEq: {preview: string, code: string, name: string}, eq: {preview: string, code: string, name: string}, gt: {preview: string, code: string, name: string}, null: {code: string, name: string}, today: {code: string, name: string}, day3: {code: string, name: string}, noEq: {preview: string, code: string, name: string}, noNull: {code: string, name: string}, between: {preview: string, code: string, name: string}, fuzzy: {preview: string, code: string, name: string}}}
 */
export const filterCodes = {
    'eq': {
        // code: 'equal',
        code: QueryFilter.EQUAL,
        name: '等于',
        preview: ''
    },
    'noEq': {
        // code: 'noEqual',
        code: QueryFilter.NOT_EQUAL,
        name: '不等于',
        preview: '!='
    }, // 不等于
    'noNull': {
        // code: 'noNull',
        code: QueryFilter.IS_NOT_NULL,
        name: '非空'
    }, // 非空
    'null': {
        // code: 'null',
        code: QueryFilter.IS_NULL,
        name: '为空'
    }, // 为空
    'between': {
        // code: 'between',
        code: QueryFilter.BETWEEN,
        name: '介于',
        preview: ''
    },
    'today': {
        code: 'today',
        name: '今天'
    },
    'day3': {
        code: 'day3',
        name: '最近三天'
    },
    'week1': {
        code: 'week1',
        name: '最近一周'
    },
    'month1': {
        code: 'month1',
        name: '最近一月'
    },
    'gt': {
        // code: 'gt',
        code: QueryFilter.GREATER_THAN,
        name: '大于',
        preview: '＞'
    },
    'gtEq': {
        // code: 'gtEq',
        code: QueryFilter.GREATER_THAN_OR_EQUAL,
        name: '大于等于',
        preview: '≥'
    },
    'lt': {
        // code: 'lt',
        code: QueryFilter.LESS_THAN,
        name: '小于',
        preview: '＜'
    },
    'ltEq': {
        // code: 'ltEq',
        code: QueryFilter.LESS_THAN_OR_EQUAL,
        name: '小于等于',
        preview: '≤'
    },
    'yes': {
        code: 'yes',
        name: '是'
    },
    'no': {
        code: 'no',
        name: '否'
    },
    'fuzzy': {
        code: 'fuzzy',
        name: '全模糊匹配',
        preview: ''
    },
    'in': {
        code: QueryFilter.IN,
        name: '包含',
        preview: 'in'
    },
    'notIn': {
        code: QueryFilter.NOT_IN,
        name: '不包含',
        preview: 'notIn'
    },
};

/**
 * 根据 code 从 filterCodes 获取枚举数据
 * @param code
 * @return {null}
 */
export const getFilterByCode = (code) => {
    let reObj = null;
    forEach(filterCodes, (filterItem) => {

        if (code === filterItem.code) {
            reObj = filterItem;
            return false; // return false 可退出 forEach 方法
        }
    });

    return reObj;
};

/**
 * 获取用于回显“过滤条件”的数据对象。
 * 例如：业务时间：
 * @param value {{}} 过滤组件的值
 * @param value.comboVal
 * @param value.compVal
 * @param value.fieldName {string} 字段名称
 * @param value.label {string} 字段的本标签
 * @param value.componentType {string} 组件类型。对应 ComponentType
 * @param moreProps {{}} 额外的属性
 * @param moreProps.formatMsgByCn {function} 国际化方法
 * @return {{fieldNames: string, label: string, text: string} | null}
 */
export function getFilterPreview({comboVal, compVal, fieldName, label, componentType, format, floatNum, selector}, {formatMsgByCn, appins}) {
    const filterItem = getFilterByCode(comboVal);
    /**
     * 用于回显筛选条件的值
     * {fieldNames: '字段名', label: '字段中文描述', text: '回显文本'}
     */
    let previewValue = {
        fieldNames: fieldName,
        label: label,
        text: ''
    };
    let needPreview = false;

    if (-1 === [
        filterCodes.null.code, filterCodes.noNull.code,
        filterCodes.today.code, filterCodes.week1.code,
        filterCodes.day3.code, filterCodes.month1.code
    ].indexOf(comboVal)) {

        if (filterItem && isNotEmpty(compVal)) {
            let tmpTxt = 'preview' in filterItem ? filterItem.preview : filterItem.name;
            let previewTxt = comboVal === filterCodes.eq.code ?
                '' : formatMsgByCn(tmpTxt);

            let previewContent = dealValuePreview(componentType, compVal, {formatMsgByCn, format, floatNum, selector, appins});
            if (isString(previewContent) || isNumber(previewContent)) {
                previewValue.text = `${previewTxt} ${previewContent}`;
            } else {
                previewValue.text = (<>{previewTxt} {previewContent}</>);
                previewValue.isJsx = true;  // 标识是 jsx 内容
            }
            needPreview = true;
        }
    } else {
        // 为空、非空时，不需要传 compVal
        previewValue.text = formatMsgByCn(filterItem.name);
        needPreview = true;
    }

    // console.log('previewValue', previewValue, {comboVal, compVal, fieldName, label, componentType});
    return needPreview ? previewValue : null;
}

function dealValuePreview(type, compVal, {formatMsgByCn, format, floatNum, selector, appins}) {
    let previewVal = compVal;

    if (!isArray(compVal)) {
        let val = compVal;
        switch (type) {
            case ComponentType.NUMBER_INPUT:
                previewVal = isNotEmpty(val) ? previewNumber(val, floatNum, format) : '';
                break;
            case ComponentType.CALENDAR:
                previewVal = isNumber(val) || isDateIns(val) ? myFormatTime(val, format || '') : '';
                break;
            case ComponentType.FINDER:
                previewVal = val ? val.name || val.code || '' : '';
                break;
            case ComponentType.CHECK_BOX:
                let tmpVal = isBoolean(compVal) ? compVal : '1' === compVal;
                previewVal = formatMsgByCn(tmpVal ? '是' : '否');
                break;
            case  ComponentType.COMBO_BOX:
                previewVal = <ComboBase selector={selector} value={compVal} readonly={true}/>;
                break;
            case ComponentType.TAG_EDITOR:
                let {libraries = []} = appins && appins.tagConfig || {};
                let tags = [];
                if (!isEmpty(libraries) && !isEmpty(val)) {
                    val = val.split(',');
                    let optDataObj = {};
                    forEach(libraries, item => {
                        optDataObj[item.id + ''] = item.name || item.id;
                    });

                    forEach(val, item => {
                        if (!isEmpty(optDataObj[item])) {
                            tags.push(optDataObj[item]);
                        }
                    });
                    previewVal = <span>{tags.join('、')}</span>;
                }
                break;
        }
    }

    if (isArray(compVal)) {
        let tmpArr = compVal;

        switch (type) {
            case ComponentType.NUMBER_INPUT:
                tmpArr = map(compVal, (val) => (
                    isNotEmpty(val) ? previewNumber(val, floatNum, format) : ''
                ));
                break;
            case ComponentType.CALENDAR:
                tmpArr = map(compVal, (val) => (
                    isNumber(val) || isDateIns(val) ? myFormatTime(val, format) : ''
                ));
                break;
            case ComponentType.FINDER:
                tmpArr = map(compVal, (val) => (
                    val ? val.name || val.code || '' : ''
                ));
                break;
            case ComponentType.ARRANGE_COMBINATIONS:
                tmpArr = map(compVal, (val) => (
                    val ? val.name || val.code || '' : ''
                ));
                break;
        }

        previewVal = tmpArr.join(' ~ ');
    }

    return previewVal;
}